Security News
vlt Debuts New JavaScript Package Manager and Serverless Registry at NodeConf EU
vlt introduced its new package manager and a serverless registry this week, innovating in a space where npm has stagnated.
The ufo npm package provides utilities for URL formatting and normalization. It helps in parsing, resolving, and normalizing URLs, as well as providing utilities for handling query parameters.
Parsing and normalizing URLs
This feature allows you to normalize URLs, which includes removing the default port for HTTP and HTTPS, decoding unnecessary percent-encoded characters, and removing duplicate slashes.
const { normalizeURL } = require('ufo');
const normalizedUrl = normalizeURL('http://example.com:80/path/');
Handling query parameters
This feature enables you to easily add query parameters to a URL, which can be useful for constructing URLs with dynamic query strings.
const { withQuery } = require('ufo');
const urlWithQuery = withQuery('http://example.com', { query: 'value' });
Joining URLs
This feature is used to concatenate URL parts safely, ensuring that there are no duplicate slashes and that the query string is properly appended.
const { joinURL } = require('ufo');
const fullUrl = joinURL('http://example.com', '/path', '?query=value');
The url-parse package offers similar URL parsing and manipulation functionalities. It provides a more detailed breakdown of the URL components and can be used in both Node.js and browser environments, whereas ufo is more focused on URL normalization and handling.
The qs package is used for parsing and stringifying query strings. It goes into more depth for handling nested objects within query strings compared to ufo's simpler query parameter utilities.
URI.js is a URL mutation library that offers comprehensive URL manipulation capabilities. It has a fluent API for building and altering URL components, which might be more intuitive for some developers compared to ufo's more functional approach.
URL utils for humans.
Install using npm or your favourite package manager:
Install package:
# npm
npm install ufo
# yarn
yarn add ufo
# pnpm
pnpm install ufo
# bun
bun install ufo
Import utils:
// ESM
import { normalizeURL, joinURL } from "ufo";
// CommonJS
const { normalizeURL, joinURL } = require("ufo");
// Deno
import { parseURL } from "https://unpkg.com/ufo/dist/index.mjs";
decode(text)
Decode text using decodeURIComponent
. Returns the original text if it fails.
decodePath(text)
Decode path section of URL (consistent with encodePath for slash encoding).
decodeQueryKey(text)
Decodes query key (consistent with encodeQueryKey
for plus encoding).
decodeQueryValue(text)
Decode query value (consistent with encodeQueryValue for plus encoding).
encode(text)
Encode characters that need to be encoded on the path, search and hash sections of the URL.
encodeHash(text)
Encode characters that need to be encoded on the hash section of the URL.
encodeHost(name)
Encodes hostname with punycode encoding.
encodeParam(text)
Encode characters that need to be encoded on the path section of the URL as a param. This function encodes everything encodePath
does plus the slash (/
) character.
encodePath(text)
Encode characters that need to be encoded on the path section of the URL.
encodeQueryKey(text)
Encode characters that need to be encoded query values on the query section of the URL and also encodes the =
character.
encodeQueryValue(input)
Encode characters that need to be encoded query values on the query section of the URL.
parseAuth(input)
Takes a string of the form username:password
and returns an object with the username and password decoded.
parseFilename(input)
Parses a url and returns last segment in path as filename.
If { strict: true }
is passed as the second argument, it will only return the last segment only if ending with an extension.
Example:
// Result: filename.ext
parseFilename("http://example.com/path/to/filename.ext");
// Result: undefined
parseFilename("/path/to/.hidden-file", { strict: true });
parseHost(input)
Takes a string, and returns an object with two properties: hostname
and port
.
parsePath(input)
Splits the input string into three parts, and returns an object with those three parts.
parseURL(input, defaultProto?)
Takes a URL string and returns an object with the URL's protocol
, auth
, host
, pathname
, search
, and hash
.
Example:
parseURL("http://foo.com/foo?test=123#token");
// { protocol: 'http:', auth: '', host: 'foo.com', pathname: '/foo', search: '?test=123', hash: '#token' }
parseURL("foo.com/foo?test=123#token");
// { pathname: 'foo.com/foo', search: '?test=123', hash: '#token' }
parseURL("foo.com/foo?test=123#token", "https://");
// { protocol: 'https:', auth: '', host: 'foo.com', pathname: '/foo', search: '?test=123', hash: '#token' }
stringifyParsedURL(parsed)
Takes a ParsedURL
object and returns the stringified URL.
Example:
const obj = parseURL("http://foo.com/foo?test=123#token");
obj.host = "bar.com";
stringifyParsedURL(obj); // "http://bar.com/foo?test=123#token"
encodeQueryItem(key, value)
Encodes a pair of key and value into a url query string value.
If the value is an array, it will be encoded as multiple key-value pairs with the same key.
parseQuery(parametersString)
Parses and decodes a query string into an object.
input can be a query string with or without the leading ?
stringifyQuery(query)
Stringfies and encodes a query object into a query string.
cleanDoubleSlashes(input)
Removes double slashes from the URL.
Example:
cleanDoubleSlashes("//foo//bar//"); // "/foo/bar/"
cleanDoubleSlashes("http://example.com/analyze//http://localhost:3000//");
// Returns "http://example.com/analyze/http://localhost:3000/"
getQuery(input)
Parses and decods the query object of an input URL into an object.
Example:
getQuery("http://foo.com/foo?test=123&unicode=%E5%A5%BD");
// { test: "123", unicode: "好" }
hasLeadingSlash(input)
Checks if the input has a leading slash. (e.g. /foo
)
hasProtocol(inputString, opts)
hasTrailingSlash(input, respectQueryAndFragment?)
Checks if the input has a trailing slash.
isEmptyURL(url)
Checks if the input url is empty or /
.
isEqual(a, b, options)
Checks if two paths are equal regardless of encoding, trailing slash, and leading slash differences.
You can make slash check strict by setting { trailingSlash: true, leadingSlash: true }
as options.
You can make encoding check strict by setting { encoding: true }
as options.
Example:
isEqual("/foo", "foo"); // true
isEqual("foo/", "foo"); // true
isEqual("/foo bar", "/foo%20bar"); // true
// Strict compare
isEqual("/foo", "foo", { leadingSlash: true }); // false
isEqual("foo/", "foo", { trailingSlash: true }); // false
isEqual("/foo bar", "/foo%20bar", { encoding: true }); // false
isNonEmptyURL(url)
Checks if the input url is not empty nor /
.
isRelative(inputString)
Check if a path starts with ./
or ../
.
Example:
isRelative("./foo"); // true
isSamePath(p1, p2)
Check two paths are equal or not. Trailing slash and encoding are normalized before comparison.
Example:
isSamePath("/foo", "/foo/"); // true
isScriptProtocol(protocol?)
Checks if the input protocol is any of the dangerous blob:
, data:
, javascript
: or vbscript:
protocols.
joinRelativeURL()
Joins multiple URL segments into a single URL and also handles relative paths with ./
and ../
.
Example:
joinRelativeURL("/a", "../b", "./c"); // "/b/c"
joinURL(base)
Joins multiple URL segments into a single URL.
Example:
joinURL("a", "/b", "/c"); // "a/b/c"
normalizeURL(input)
Normlizes inputed url:
Example:
normalizeURL("test?query=123 123#hash, test");
// Returns "test?query=123%20123#hash,%20test"
normalizeURL("http://localhost:3000");
// Returns "http://localhost:3000"
resolveURL(base)
Resolves multiple URL segments into a single URL.
Example:
resolveURL("http://foo.com/foo?test=123#token", "bar", "baz");
// Returns "http://foo.com/foo/bar/baz?test=123#token"
withBase(input, base)
Ensures the URL or pathname has a trailing slash.
If input aleady start with base, it will not be added again.
withFragment(input, hash)
Add/Replace the fragment section of the URL.
Example:
withFragment("/foo", "bar"); // "/foo#bar"
withFragment("/foo#bar", "baz"); // "/foo#baz"
withFragment("/foo#bar", ""); // "/foo"
withHttp(input)
Adds or replaces url protocol to http://
.
Example:
withHttp("https://example.com"); // http://example.com
withHttps(input)
Adds or replaces url protocol to https://
.
Example:
withHttps("http://example.com"); // https://example.com
withLeadingSlash(input)
Ensures the URL or pathname has a leading slash.
withoutBase(input, base)
Removes the base from the URL or pathname.
If input does not start with base, it will not be removed.
withoutFragment(input)
Removes the fragment section from the URL.
Example:
withoutFragment("http://example.com/foo?q=123#bar")
// Returns "http://example.com/foo?q=123"
withoutHost(input)
Removes the host from the URL preserving everything else.
Example:
withoutHost("http://example.com/foo?q=123#bar")
// Returns "/foo?q=123#bar"
withoutLeadingSlash(input)
Removes leading slash from the URL or pathname.
withoutProtocol(input)
Removes the protocol from the input.
Example:
withoutProtocol("http://example.com"); // "example.com"
withoutTrailingSlash(input, respectQueryAndFragment?)
Removes trailing slash from the URL or pathname.
If second argument is true, it will only remove the trailing slash if it's not part of the query or fragment with cost of more expensive operations.
Example:
withoutTrailingSlash("/foo/"); // "/foo"
withoutTrailingSlash("/path/?query=true", true); // "/path?query=true"
withProtocol(input, protocol)
Adds or Replaces protocol of the input URL.
Example:
withProtocol("http://example.com", "ftp://"); // "ftp://example.com"
withQuery(input, query)
Add/Replace the query section of the URL.
Example:
withQuery("/foo?page=a", { token: "secret" }); // "/foo?page=a&token=secret"
withTrailingSlash(input, respectQueryAndFragment?)
Ensures url ends with a trailing slash.
If seccond argument is true
, it will only add the trailing slash if it's not part of the query or fragment with cost of more expensive operation.
Example:
withTrailingSlash("/foo"); // "/foo/"
withTrailingSlash("/path?query=true", true); // "/path/?query=true"
Special thanks to Eduardo San Martin Morote (posva) for encoding utilities
FAQs
URL utils for humans
We found that ufo demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
vlt introduced its new package manager and a serverless registry this week, innovating in a space where npm has stagnated.
Security News
Research
The Socket Research Team uncovered a malicious Python package typosquatting the popular 'fabric' SSH library, silently exfiltrating AWS credentials from unsuspecting developers.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.